//
// Created by 成飞 on 2024/1/5.
//

#ifndef ORDERKV_CONF_HPP
#define ORDERKV_CONF_HPP

#include "conf_parser.hpp"

namespace conf{

    class Env{ //Singleton
    private:
        SectionCollect collect;

        Env(){
            default_init();
            file_init();
        }

        void default_init(){
            Section *section = collect.add_section("db");
            std::map<std::string, std::string> defaultInfo{
                    {"project_path", PROJECT_PATH},
                    {"startup_conf_path", std::string(PROJECT_PATH) + "/db.conf"}
            };
            section->add_key_value(defaultInfo);
        }

        void file_init(){
            ConfReadParser confParser(get_section_attr("db", "startup_conf_path"), collect);
            confParser.Process();
        }

    public:
        static Env& instance(){
            static Env instance;
            return instance;
        }

        std::string get_section_attr(const std::string &section, const std::string &attr){
            Section *pSection = collect.get_section(section);
            if (pSection == nullptr) return "";
            std::string *pValue = pSection->get_value(attr);
            return pValue ? *pValue : "";
        }

        bool set_section_attr(const std::string &section, const std::string &attr, const std::string &value){
            Section *pSection = collect.get_section(section);
            if(pSection == nullptr) return false;
            std::string *pValue = pSection->get_value(attr);
            if (pValue == nullptr) return false;
            *pValue = value;
            return true;
        }

        void show_all_attrs(){
            collect.show(std::cout);
        }
    };

    class Util{
    public:
        static long convert_to_byte_number(const std::string& input){
            size_t len = input.length();
            std::string numPart;
            long multiplier = 1;

            if (input.substr(len - 2) == "KB") {
                numPart = input.substr(0, len-2);
                multiplier = 1024;
            } else if (input.substr(len - 2) == "MB") {
                numPart = input.substr(0, len-2);
                multiplier = 1024 * 1024;
            }else if(input.substr(len - 2) == "GB") {
                numPart = input.substr(0, len-2);
                multiplier = 1024 * 1024 * 1024;
            } else if (input.substr(len - 1) == "B") {
                numPart = input.substr(0, len-1);
            } else{
                throw std::invalid_argument("wrong input: " + input);
            }
            return std::stol(numPart) * multiplier;
        }
    };


}
#endif //ORDERKV_CONF_HPP
